//
//  ALMacros.h
//  AppLovinSDK
//
//  Created by Thomas So on 1/1/22.
//

NS_ASSUME_NONNULL_BEGIN

        NS_INLINE

BOOL isMainQueue(void) {
    return [NSThread
    isMainThread];
}

NS_INLINE void deferToNextMainQueueRunloop(void (^block)(void)) {
    [[NSOperationQueue
    mainQueue] addOperationWithBlock:
    block];
}

NS_INLINE void dispatchOnMainQueueNow(void (^block)(void)) {
    dispatch_async(dispatch_get_main_queue(), block);
}

NS_INLINE void dispatchOnMainQueue(void (^block)(void)) {
    if (isMainQueue()) {
        block();
    } else {
        deferToNextMainQueueRunloop(block);
    }
}

NS_INLINE void dispatchOnMainQueueImmediate(void (^block)(void)) {
    if (isMainQueue()) {
        block();
    } else {
        dispatchOnMainQueueNow(block);
    }
}

NS_INLINE void dispatchOnMainQueueAfter(double delay, dispatch_block_t __nonnull block) {
    if (delay > 0) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)),
                       dispatch_get_main_queue(), block);
    } else {
        dispatchOnMainQueueImmediate(block);
    }
}

NS_INLINE void
dispatchOnMainQueueAfterAndDeferToNextMainQueueRunloop(double delay, dispatch_block_t __nonnull
                                                       block) {
    if (delay > 0) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)),
                       dispatch_get_main_queue(), block);
    } else {
        deferToNextMainQueueRunloop(block);
    }
}

NS_INLINE void dispatchSyncOnMainQueue(dispatch_block_t __nonnull block) {
    // Cannot call dispatch_sync on same queue results in deadlock - so just run op if main queue already
    if (isMainQueue()) {
        block();
    } else {
        dispatch_sync(dispatch_get_main_queue(), block);
    }
}

NS_INLINE void dispatchOnGlobalQueueAfter(dispatch_queue_priority_t priority, double delay,
                                          dispatch_block_t __nonnull block) {
    dispatch_queue_t globalQueue = dispatch_get_global_queue(priority, 0);

    if (delay > 0) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)),
                       globalQueue, block);
    } else {
        dispatch_async(globalQueue, block);
    }
}

NS_ASSUME_NONNULL_END
